package com.mall.util

import com.mall.config.JwtConfig
import io.jsonwebtoken.Claims
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.security.Keys
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import java.util.Date
import javax.crypto.SecretKey

/**
 * JWT工具类
 */
@Component
class JwtUtil(private val jwtConfig: JwtConfig) {
    private val secret: String
        get() = jwtConfig.secret
    
    private val expiration: Long
        get() = jwtConfig.expiration
    
    /**
     * 生成JWT令牌
     */
    fun generateToken(admin: com.mall.entity.Admin): String {
        val now = Date()
        val expiryDate = Date(now.time + expiration * 1000)
        
        return Jwts.builder()
            .setSubject(admin.username)
            .setId(admin.id.toString())
            .setIssuedAt(now)
            .setExpiration(expiryDate)
            .signWith(getSignKey())
            .compact()
    }
    
    /**
     * 从JWT令牌中获取用户名
     */
    fun getUsernameFromToken(token: String?): String {
        if (token == null) throw IllegalArgumentException("Token cannot be null")
        val claims = getAllClaimsFromToken(token)
        return claims.subject
    }

    /**
     * 从JWT令牌中获取用户ID
     */
    fun getIdFromToken(token: String?): String {
        if (token == null) throw IllegalArgumentException("Token cannot be null")
        val claims = getAllClaimsFromToken(token)
        return claims.id
    }
    
    /**
     * 验证JWT令牌
     */
    fun validateToken(token: String?): Boolean {
        if (token == null) return false
        try {
            Jwts.parserBuilder()
                .setSigningKey(getSignKey())
                .build()
                .parseClaimsJws(token)
            return true
        } catch (e: Exception) {
            return false
        }
    }
    
    /**
     * 从JWT令牌中获取所有声明
     */
    private fun getAllClaimsFromToken(token: String): Claims {
        return Jwts.parserBuilder()
            .setSigningKey(getSignKey())
            .build()
            .parseClaimsJws(token)
            .body
    }
    
    /**
     * 获取签名密钥
     */
    private fun getSignKey(): SecretKey {
        val keyBytes = secret.toByteArray()
        return Keys.hmacShaKeyFor(keyBytes)
    }
}